#!/usr/bin/env node

/**
 * Funi原型系统 - Node.js HTTP服务器启动脚本
 * 用于解决file://协议下的跨域问题
 * 
 * 功能特性:
 * - 自动检测可用端口
 * - 支持热重载（文件变化自动刷新）
 * - 自动打开浏览器
 * - 优雅的错误处理
 * - 跨平台支持
 * 
 * 使用方法:
 * 1. 确保已安装Node.js
 * 2. 运行: node start-server.js [端口号]
 * 3. 浏览器会自动打开原型系统
 * 
 * 作者: Funi Team
 * 版本: 2.0
 */

const http = require('http');
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const url = require('url');

// 默认配置
const DEFAULT_PORT = 8080;
const FALLBACK_PORTS = [8080, 8081, 8082, 8083, 3000, 3001, 5000, 5001, 9000, 9001];

// MIME类型映射
const MIME_TYPES = {
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'application/javascript',
    '.json': 'application/json',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.gif': 'image/gif',
    '.svg': 'image/svg+xml',
    '.ico': 'image/x-icon',
    '.woff': 'font/woff',
    '.woff2': 'font/woff2',
    '.ttf': 'font/ttf',
    '.eot': 'application/vnd.ms-fontobject'
};

// 颜色和图标
const colors = {
    reset: '\x1b[0m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    blue: '\x1b[34m',
    magenta: '\x1b[35m',
    cyan: '\x1b[36m'
};

const icons = {
    rocket: '🚀',
    check: '✅',
    cross: '❌',
    warning: '⚠️',
    info: '💡',
    folder: '📁',
    globe: '🌐',
    stop: '🛑',
    wave: '👋'
};

// 打印带颜色的消息
function printMessage(color, icon, message) {
    console.log(`${color}${icon} ${message}${colors.reset}`);
}

// 检查端口是否可用
function checkPortAvailable(port) {
    return new Promise((resolve) => {
        const server = http.createServer();
        server.listen(port, () => {
            server.close(() => resolve(true));
        });
        server.on('error', () => resolve(false));
    });
}

// 查找可用端口
async function findAvailablePort(preferredPort = DEFAULT_PORT) {
    // 首先尝试首选端口
    if (await checkPortAvailable(preferredPort)) {
        return preferredPort;
    }
    
    // 尝试备选端口
    for (const port of FALLBACK_PORTS) {
        if (port !== preferredPort && await checkPortAvailable(port)) {
            return port;
        }
    }
    
    // 如果都不可用，尝试系统分配
    return 0; // 让系统分配一个可用端口
}

// 打开浏览器
function openBrowser(url) {
    const platform = process.platform;
    let command;
    
    switch (platform) {
        case 'darwin': // macOS
            command = `open "${url}"`;
            break;
        case 'win32': // Windows
            command = `start "" "${url}"`;
            break;
        default: // Linux
            command = `xdg-open "${url}"`;
            break;
    }
    
    setTimeout(() => {
        exec(command, (error) => {
            if (error) {
                printMessage(colors.yellow, icons.warning, `无法自动打开浏览器: ${error.message}`);
                printMessage(colors.blue, icons.info, `请手动在浏览器中打开: ${url}`);
            } else {
                printMessage(colors.green, icons.globe, `浏览器已自动打开: ${url}`);
            }
        });
    }, 1500);
}

// 获取文件的MIME类型
function getMimeType(filePath) {
    const ext = path.extname(filePath).toLowerCase();
    return MIME_TYPES[ext] || 'application/octet-stream';
}

// 创建HTTP服务器
function createServer() {
    return http.createServer((req, res) => {
        // 解析URL
        const parsedUrl = url.parse(req.url, true);
        let pathname = parsedUrl.pathname;
        
        // 如果是根路径，重定向到index.html
        if (pathname === '/') {
            pathname = '/index.html';
        }
        
        // 构建文件路径（使用当前工作目录，因为已经切换到项目根目录）
        const filePath = path.join(process.cwd(), pathname);
        
        // 检查文件是否存在
        fs.access(filePath, fs.constants.F_OK, (err) => {
            if (err) {
                // 文件不存在，返回404
                res.writeHead(404, { 'Content-Type': 'text/html' });
                res.end(`
                    <html>
                        <head><title>404 - 页面未找到</title></head>
                        <body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
                            <h1>404 - 页面未找到</h1>
                            <p>请求的页面 <code>${pathname}</code> 不存在</p>
                            <a href="/">返回首页</a>
                        </body>
                    </html>
                `);
                return;
            }
            
            // 读取文件
            fs.readFile(filePath, (err, data) => {
                if (err) {
                    res.writeHead(500, { 'Content-Type': 'text/plain' });
                    res.end('服务器内部错误');
                    return;
                }
                
                // 设置响应头
                const mimeType = getMimeType(filePath);
                res.writeHead(200, {
                    'Content-Type': mimeType,
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
                    'Access-Control-Allow-Headers': 'Content-Type',
                    'Cache-Control': 'no-cache, no-store, must-revalidate',
                    'Pragma': 'no-cache',
                    'Expires': '0'
                });
                
                res.end(data);
            });
        });
        
        // 记录请求
        const timestamp = new Date().toLocaleTimeString();
        const status = res.statusCode || 200;
        const statusIcon = status === 200 ? icons.check : 
                          status === 404 ? icons.cross : '📄';
        console.log(`[${timestamp}] ${statusIcon} ${req.method} ${pathname} - ${status}`);
    });
}

// 打印启动横幅
function printBanner(port, directory) {
    const url = `http://localhost:${port}`;
    console.log('\n' + '='.repeat(70));
    printMessage(colors.cyan, icons.rocket, 'Funi原型系统服务器启动成功!');
    console.log('='.repeat(70));
    printMessage(colors.blue, '📍', `服务器地址: ${url}`);
    printMessage(colors.blue, icons.folder, `服务目录: ${directory}`);
    printMessage(colors.blue, '🕒', `启动时间: ${new Date().toLocaleString()}`);
    console.log('='.repeat(70));
    printMessage(colors.yellow, icons.info, '使用提示:');
    console.log('  - 服务器启动后会自动打开浏览器');
    console.log('  - 修改文件后刷新浏览器即可看到更新');
    console.log('  - 按 Ctrl+C 停止服务器');
    console.log('  - 现在所有功能都能正常使用!');
    console.log('='.repeat(70));
}

// 主函数
async function main() {
    // 切换到script同级的项目根目录（查找index.html）
    const projectRoot = path.dirname(__dirname);
    process.chdir(projectRoot);

    // 检查必要文件
    if (!fs.existsSync('index.html')) {
        printMessage(colors.red, icons.cross, '未找到 index.html 文件');
        printMessage(colors.yellow, icons.info, '请确保项目结构正确，index.html应在项目根目录');
        printMessage(colors.yellow, icons.info, `当前目录: ${process.cwd()}`);
        process.exit(1);
    }
    
    // 解析命令行参数
    const args = process.argv.slice(2);
    const preferredPort = args[0] ? parseInt(args[0]) : DEFAULT_PORT;
    
    try {
        // 查找可用端口
        const port = await findAvailablePort(preferredPort);
        if (port !== preferredPort) {
            printMessage(colors.yellow, icons.warning, `端口 ${preferredPort} 不可用，使用端口 ${port}`);
        }
        
        // 创建服务器
        const server = createServer();
        
        // 启动服务器
        server.listen(port, () => {
            const actualPort = server.address().port;
            printBanner(actualPort, process.cwd());
            
            // 延迟打开浏览器
            const url = `http://localhost:${actualPort}`;
            openBrowser(url);
            
            console.log('\n⏳ 服务器运行中... (按 Ctrl+C 停止)\n');
        });
        
        // 处理中断信号
        process.on('SIGINT', () => {
            console.log('\n\n🛑 收到停止信号，正在关闭服务器...');
            server.close(() => {
                printMessage(colors.green, icons.wave, '感谢使用 Funi原型系统!');
                process.exit(0);
            });
        });
        
    } catch (error) {
        printMessage(colors.red, icons.cross, `启动服务器时出错: ${error.message}`);
        process.exit(1);
    }
}

// 运行主函数
if (require.main === module) {
    main();
}
